var MApp = {
	divDataPrefix : 'data-app-',
	parseData : function (divContent) {
		return BigUtil.parseData(divContent, MApp.divDataPrefix);
	},
	createDomprefix : function (tabAppData) {
		if (!tabAppData.domprefix) {
			tabAppData.domprefix = 'RANDOM' + BigUtil.random(1000, 10000);
		}
	},
	tableSelectedClass : 'bg-gray',
	refreshTab : function () {
		var div = $('div[id^=divBigContentTab_]:last');
		if (div.data('appData')) {
			MApp.load(div, div.data('appData'));
			return;
		}
		BigUtil.refreshTab();
	},
	createTab : function (appData, title) {
		var div = BigUtil.createTab({
			title : title
		});
		MApp.load(div, appData);
	},
	/**
	 *
	 * @param selector 可以是空、选择器字符串或者jquery对象
	 */
	load : function(selector, appData) {
		// 加载数据的div
		var divContent = BigUtil.getObject(selector, '[data-app-autoload=true]');
	    if (!divContent || divContent.length == 0) {
	        return;
	    }
	    if (appData) {
	    	delete appData.data;
	    	appData = BigUtil.clone({url : appData.template}, appData);
	    	appData = BigUtil.clone(MApp.parseData(divContent), appData);
	    } else {
	    	appData = MApp.parseData(divContent);
	    }
	    // 如果没有domprefix，则产生一个随机的
	    MApp.createDomprefix (appData);
	    divContent.data('appData', appData);
	    if (divContent.attr('data-app-subtype') == 'update') {
			divContent.load ('/meta/' + appData.type + '/loadUpdateForm', appData, function () {
				var updateForm = divContent.find('form:first');
				MApp.initForm(appData, updateForm, false);
				updateForm.find('button[data-app-buttontype=submitUpdate]').click(function () {
					BigUtil.ajaxForm({
						form : updateForm,
						url : '/meta/' + appData.type + '/update',
						params : MApp.addRequestJson(appData, $(this))
					});
				});
		    });
			return;
		}
	    var callback;
	    try {
	        callback = eval('(MApp.' + appData.type + 'Init)');
	    } catch (e) {
	        callback = function () {
	        }
	    }
	    divContent.load ('/' + appData.url, appData, function () {
	    	callback (appData);
	    });
	},
	getDomId : function (appData, suffix) {
		if (BigUtil.isEmpty (suffix)) {
			return appData.domprefix + "-" + appData.id;
		}
		return appData.domprefix + "-" + appData.id + "-" + suffix;
	},
	/**
	 * 获取列表视图div的jquery对象
	 * @param appData
	 * @returns {void|jQuery|HTMLElement}
	 */
	listDiv : function (appData) {
		return $('[data-app-list=' + MApp.getDomId(appData) + '-list]');
	},
	/**
	 * 加载列表数据
	 * @param appData
	 * @param page
	 */
	loadList : function (appData, page) {
		// 获取列表
		var divList = MApp.listDiv(appData);
		if (page == undefined) {
			page = divList.find('.bg-light-blue-active').attr('data-app-page');
			if (page == undefined) {
				page = 1;
			}
		} else if (page < 1) {
			page = 1;
		}
		// 获取列表数据
		var crudData = BigUtil.clone(MApp.parseData (divList), appData);
		// 设置分页参数
		crudData.page = page;
		// 获取列表外的form，其中包含查询字段
		var formData = divList.parents('form').eq(0).serializeArray();
		divList.load (divList.attr('data-app-url'), BigUtil.mergeFormData(formData, crudData), function () {
			// 查找所有需要ajax的td，并将数据放入data中，key为data-app-listajax的值（也就是ajax请求的url），value为列表属性数据的数组
			var data = {};
			divList.find ('td[data-app-listajax]').each (function () {
				var keyValue = MApp.getListRowPkValue($(this).parents('tr:first'));
				var lpId = $(this).attr('data-app-listproperty');
				var url = $(this).attr('data-app-listajax');
				if (data[url]) {
					data[url].push(lpId + ':' + keyValue);
				} else {
					data[url] = [lpId + ':' + keyValue];
				}
			});
			// 发送ajax请求，并获取数据更新td内容
			for (var url in data) {
				var params = { id : appData.id, listPropertyData : data[url].join(','), requestjson : appData.requestjson};
				$.post(url, params, function (json) {
					if (json.success) {
						// 更新td数据
						divList.find ('td[data-app-listajax]').each (function () {
							var keyValue = MApp.getListRowPkValue($(this).parents('tr:first'));
							var lpId = $(this).attr('data-app-listproperty');
							$(this).text(json.content[lpId + ':' + keyValue]);
						});
					} else {
						alert(json.msg);
					}
				});
			}
			// 如果leditor，则需要init相关控件
			if (appData.type == 'leditor') {
				divList.find('tr').each (function () {
					var tr = $(this);
					MApp.initForm(appData, tr, tr.find('[data-app-buttontype="submitCreate"]').length == 1);
				});
			}
		});
	},
	/**
	 * 获取列表选中行主键值数组
	 * @param appData
	 * @param listDiv
	 * @returns {Array}
	 */
	getListPkValues : function (appData, listDiv) {
		var trs = listDiv.find ('tr.' + MApp.tableSelectedClass);
		var values = [];
		trs.each(function () {
			var tr = $(this);
			var row = JSON.parse(tr.attr('data-app-row'));
			var pk = tr.attr('data-app-pk');
			values.push (row[pk]);
		});
		return values;
	},
	/**
	 * 按钮点击时，验证selectType
	 */
	validateListSelection : function (appData, listDiv, selectType) {
		var trs = listDiv.find ('tr.' + MApp.tableSelectedClass);
		if (selectType == 'none') {
			return true;
		}
		if (selectType == 'singleornone') {
			if (trs.length > 1) {
				alert('您最多只能选择一条记录！');
				return false;
			}
			return true;
		}
		if (selectType == 'single') {
			if (trs.length == 1) {
				return true;
			}
			alert('您还没有选择一条记录！');
			return false;
		}
		if (selectType == 'multiple') {
			if (trs.length > 0) {
				return true;
			}
			alert('您还没有选择一条记录！');
			return false;
		}
	},
	/**
	 * 表单中的objectSelector/objectInputor控件已选记录的按钮
	 * @param value
	 * @param name
	 * @returns {string}
	 */
	createRelatedNameButtons : function (value, name, type) {
		return BigUtil.createRelatedNameButtons(value, name, type);
	},
	initObjectSelector: function (opts) {
		var hiddens = BigUtil.getObject(opts.objectSelector, 'input[data-app-selector]');
		hiddens.each(function () {
			var hidden = $(this);
			var selectorAppData = MApp.parseData(hidden.next().find('.input-group-addon'));
			if (hidden.attr('data-app-readonly') != 'true') {
				// 设置按钮点击事件
				hidden.next().on('click', 'button', function () {
					// 按钮点击时，会删除hidden中对应的值，并删除按钮元素
					var val = $(this).attr('data-app-value');
					var values = BigUtil.parseArray(hidden.val());
					for (var i = values.length - 1; i >= 0; i --) {
						if (values[i] == val) {
							values.splice(i, 1);
						}
					}
					hidden.val(values.join(','));
					$(this).remove();
				});
				// 创建对象选择tab
				hidden.next().find('.input-group-addon').click (function () {
					var label = $(this).parent().parent().find(':first');
					var title = label.find('span:first').text();
					if (BigUtil.isEmpty(title)) {
						title = label.text().trim();
					}
					if ($(this).attr('data-app-container') == 'tab') {
						MApp.createTab(selectorAppData, '选择：' + title);
					} else {
						BigUtil.showMainModal({
							modalAttr: 'object-selector',
							title: '选择：' + title,
							fn : function (btn, modal) {
								MApp.load(modal.find('.modal-body'), selectorAppData);
								btn.addClass('fa-check-circle');
								btn.removeClass('hidden');
								btn.text(' 确定');
								btn.unbind();
								MApp.listBtnSelectorInit(selectorAppData, modal.find('.modal-body'), selectorAppData.selectorSingle, btn);
							}
						});
					}
				});
			}
			// 加载名称按钮
			if (BigUtil.isEmpty(hidden.val())) {
				return;
			}
			var data = {
				id : selectorAppData.id,
				propertyValue : hidden.val()
			};
			$.post ('/meta/crud/loadSelectorNames', data, function (json) {
				if (json.success) {
					var values = BigUtil.parseArray(hidden.val());
					for (var i = 0; i < values.length; i ++) {
						hidden.next().find('.form-control').append(MApp.createRelatedNameButtons(values[i], json.content[i]));
					}
				}
			});
		});
	},
	initMultipleObjectSelector: function (opts) {
		var hiddens = BigUtil.getObject(opts.multipleObjectSelector, 'input[data-app-multipleselector]');

		function createButton (formGroup, value, name) {
			let appId = value.split(':')[0];
			name = '[' + formGroup.find('select option[value="' + appId + '"]').text().trim() + ']' + name;
			return MApp.createRelatedNameButtons(value, name);
		}

		hiddens.each(function () {
			var hidden = $(this);
			var formGroup = hidden.parent();
			var selectorAppData = MApp.parseData(hidden.next().find('.input-group-addon'));

			if (hidden.attr('data-app-readonly') != 'true') {
				// 设置按钮点击事件
				hidden.next().on('click', 'button', function () {
					// 按钮点击时，会删除hidden中对应的值，并删除按钮元素
					var val = $(this).attr('data-app-value');
					var values = BigUtil.parseArray(hidden.val());
					for (var i = values.length - 1; i >= 0; i --) {
						if (values[i] == val) {
							values.splice(i, 1);
						}
					}
					hidden.val(values.join(','));
					$(this).remove();
				});
				// 创建对象选择tab
				if (hidden.attr('data-app-readonly') != 'true') {
					hidden.next().find('.input-group-addon').click (function () {
						var title = formGroup.find('option:selected').text().trim();
						selectorAppData.id = formGroup.find('select').val();
						BigUtil.showMainModal({
							modalAttr: 'object-selector',
							title: '选择：' + title,
							fn : function (btn, modal) {
								MApp.load(modal.find('.modal-body'), selectorAppData);
								btn.addClass('fa-check-circle');
								btn.removeClass('hidden');
								btn.text(' 确定');
								btn.unbind();
								btn.click (function () {
									var selectedValues = BigUtil.parseArray(hidden.val());
									var rows = [];
									modal.find('.modal-body').find ('tr.' + MApp.tableSelectedClass).each(function () {
										var tr = $(this);
										var row = JSON.parse(tr.attr('data-app-row'));
										rows.push (row);
										var pk = tr.attr('data-app-pk');
										var namekey = tr.attr('data-app-namepropertyid');
										// 新选中的行的id值
										var newValue = selectorAppData.id + ':' + row[pk];
										// 选中的id转为数组，遍历其中是否包含主键值，如果包含，退出
										for (var i = 0; i < selectedValues.length; i ++) {
											if (selectedValues[i] == newValue) {
												return;
											}
										}
										if (selectorAppData.selectorsingle == 'false') {
											// 添加当前选中行的主键值
											selectedValues.push(newValue);
											hidden.val(selectedValues.join(","));
										} else {
											// 设置hidden值
											hidden.val(newValue);
											hidden.next().find('span.form-control').empty();
										}
										// 添加按钮
										hidden.next().find('span.form-control').append(MApp.createRelatedNameButtons(newValue, row[namekey]));
									});
									if (selectorAppData.selectSuccessFn) {
										selectorAppData.selectSuccessFn(selectedValues, rows, selectorAppData);
									}
									if (selectorAppData.container == 'tab') {
										BigUtil.closeTab();
									} else {
										$(this).parents('.modal:first').modal('hide');
									}
								});
							}
						});
					});
				}
			}

			// 加载名称按钮
			if (BigUtil.isEmpty(hidden.val())) {
				return;
			}
			var data = {
				propertyValue : hidden.val()
			};
			$.post ('/meta/crud/loadSelectorNames', data, function (json) {
				if (json.success) {
					var values = BigUtil.parseArray(hidden.val());
					for (var i = 0; i < values.length; i ++) {
						hidden.next().find('span.form-control').append(MApp.createRelatedNameButtons(values[i], json.content[i]));
					}
				}
			});
		});
	},
	initListor : function (opts) {
		var formGroup = BigUtil.getObject(opts.objectListor, '[data-app-listor]');
		MApp.load(formGroup.children(":last"));
	},
	/**
	 * 设置表单中的控件(objectSelector/datetime/file等)相关事件
	 * @param form
	 */
	initForm : function(appData, form, create) {
		// objectListor
		MApp.initListor({
			objectListor : form.find ('[data-app-listor]')
		});

		// objectSelector
		MApp.initObjectSelector({
			objectSelector : form.find ('input[data-app-selector]')
		});

		// multipleObjectSelector
		MApp.initMultipleObjectSelector({
			objectSelector : form.find ('input[data-app-multipleselector]')
		});

		// objectInputor
		BigUtil.initInputor({
			inputor : form.find ('[data-app-inputor]'),
			params : BigUtil.clone( create ? {} : {keyValue:form.find ('input:first').val()}, appData),
			searchUrl : '/meta/objectinputor/list',
			// autoLoad : !create,
			dataUrl : '/meta/objectinputor/value'
		});
		
		// datetime
		// startView/minView
		// 0 or 'hour' for the hour view
		// 1 or 'day' for the day view
		// 2 or 'month' for month view (the default)
		// 3 or 'year' for the 12-month overview
		// 4 or 'decade' for the 10-year overview. Useful for date-of-birth datetimepickers.
		form.find ('[data-date-format="yyyy-mm-dd hh:ii:ss"]').datetimepicker({
	        weekStart: 1,
	        todayBtn:  1,
	        autoclose: 1,
	        todayHighlight: 1,
	        startView: 2,
	        forceParse: 0,
	        showMeridian: 1
	    });
		
		// datetime
		form.find ('[data-date-format="yyyy-mm-dd"]').datetimepicker({
	        weekStart: 1,
	        todayBtn:  1,
	        autoclose: 1,
	        todayHighlight: 1,
	        startView: 2,
	        minView:1,
	        forceParse: 0,
	        showMeridian: 1
	    });

		// file // image
		BigUtil.initFile({
			file: form.find('[data-app-filetype]')
		});
		
		// radio
		BigUtil.initDictionaryRadio({dictionaryRadio: form.find('[data-app-choicetype=radio]')});

		// checkbox
		BigUtil.initDictionaryCheckbox({dictionaryCheckbox: form.find('[data-app-choicetype=checkbox]')});

		// combo
		BigUtil.initDictionaryCombo({dictionaryCombo: form.find('[data-app-choicetype=combo]')});

		// ckeditor
		form.find('[data-app-ckeditor]').each (function () {
			var formGroup = $(this);
			var editor = formGroup.find('textarea').attr('name');
			var ckeditor = CKEDITOR.replace(editor, {
				// autoUpdateElement : true,
				filebrowserBrowseUrl : '/meta/ckeditor/browse',
			    filebrowserUploadUrl : '/meta/ckeditor/upload'
			});
		});
		
		// 设置openTab按钮点击事件
		form.find('button[data-app-tabtype]').click (function () {
			MApp.clickBtnOpenTab($(this), form.find ('input:first').val(), appData);
		});
		
		// 设置requestJson按钮点击事件
		var btnRequestJson = form.find('button[data-app-requesturl]');
		btnRequestJson.unbind();
		btnRequestJson.click (function () {
			var params = BigUtil.clone(MApp.parseData($(this)), MApp.addRequestJson(appData, $(this)));
			params['selectedIds'] = form.find ('input:first').val();
			var url = $(this).attr('data-app-requesturl');
			var btn = $(this);
			$.post(url, params, function (json) {
				if (json.success) {
					MApp.submitSuccessAction(BigUtil.attr(btn, 'data-app-tabviewsubmit', 'keepTab,refreshTab'), appData);
				} else {
					alert(json.msg);
				}
			});
		});
		
		// map
		BigUtil.initMap({
			multiple : '[data-app-map] input[type=hidden]'
		});
	},
	submitSuccessAction : function (actions, appData) {
		if (!BigUtil.containsValue (actions, 'keepTab')) {
			BigUtil.closeTab();
		}
		if (BigUtil.containsValue (actions, 'refreshTab')) {
			MApp.refreshTab();
		}
		if (BigUtil.containsValue (actions, 'refreshList')) {
			MApp.loadList(appData);
		}
	},
	/**
	 * @param
	 * @param
	 * @param
	 * @param inList true表示该按钮在列表上
	 */
	clickBtnOpenTab : function (btn, selectedIds, appData, inList, tabAppData) {
		if (!tabAppData) {
			var requestjson = btn.attr('data-app-requestjson');
			if (btn.attr('data-app-tabappdata')) {
				tabAppData = JSON.parse(btn.attr('data-app-tabappdata'));
			}
			if (!BigUtil.isEmpty (requestjson)) {
				tabAppData = BigUtil.clone ({ requestjson : requestjson}, tabAppData);
			} else {
				tabAppData = BigUtil.clone ({}, tabAppData);
			}
			if (!BigUtil.isEmpty (selectedIds)) {
				tabAppData['selectedIds'] = selectedIds;
			}
		}
		MApp.createDomprefix (tabAppData);
		if (btn.attr('data-app-requestjson')) {
			var params = JSON.parse(tabAppData.requestjson);
			for (var key in params) {
				if (params[key].indexOf('tabAppData[') >= 0) {
					params[key] = eval('(' + params[key] + ')');
				}
			}
			tabAppData.requestjson = JSON.stringify(params);
		}
		var tabtype = btn.attr('data-app-tabtype');
		if (tabtype == 'appView.create') {
			BigUtil.openTab({
				title : btn.text(),
				url : '/meta/' + tabAppData.type + '/loadCreateForm',
				params : tabAppData,
				fn : function (createForm) {
					MApp.initForm (tabAppData, createForm, true);
					createForm.find('button[data-app-buttontype=submitCreate]').click (function () {
						BigUtil.ajaxForm({
							form : createForm.find('form:first'),
							url : '/meta/' + tabAppData.type + '/create',
							params : tabAppData,
							success : function (json) {
								if (json.success) {
									MApp.submitSuccessAction(BigUtil.attr(btn, 'data-app-tabviewsubmit', inList ? 'refreshList' : 'refreshTab'), appData);
								} else {
									alert (json.msg);
								}
							}
						});
					});
				}
			});
			return;
		}
		if (tabtype == 'appView.update') {
			BigUtil.openTab({
				title: btn.text(),
				url: '/meta/' + tabAppData.type + '/loadUpdateForm',
				params: tabAppData,
				fn: function (updateForm) {
					MApp.initForm(tabAppData, updateForm, false);
					updateForm.find('button[data-app-buttontype=submitUpdate]').click(function () {
						// var data = BigUtil.mergeFormData(updateForm.find('form').serializeArray(), tabAppData);
						BigUtil.ajaxForm({
							form : $(this).parents('form:first'),
							url : '/meta/' + tabAppData.type + '/update',
							params : tabAppData,
							success : function (json) {
								if (json.success) {
									MApp.submitSuccessAction(BigUtil.attr(btn, 'data-app-tabviewsubmit', inList ? 'refreshList' : 'refreshTab'), appData);
								} else {
									alert (json.msg);
								}
							}
						});
					});
				}
			});
			return;
		}	
		if (tabtype == 'app') {
			MApp.createTab(tabAppData, btn.text());
			return;
		}
		var url = btn.attr('data-app-taburl');
		BigUtil.openTab({
			title : btn.text(),
			url : url,
			params : BigUtil.clone(BigUtil.clone(MApp.parseData(btn), appData), tabAppData)
		});
	},
	/**
	 * selector列表确定按钮初始化
	 * @param appData
	 * @param listDiv
	 * @param singleSelect
	 */
	listBtnSelectorInit : function (appData, listDiv, singleSelect, btn) {
		// selector时，设置确定按钮点击事件
		if (!btn) {
			btn = listDiv.prev().find('button[data-app-buttontype=select]');
		}
		btn.click (function () {
			var hidden = $('#' + appData.domprefix);
			var selectedValues = BigUtil.parseArray(hidden.val());
			var rows = [];
			listDiv.find ('tr.' + MApp.tableSelectedClass).each(function () {
				var tr = $(this);
				var row = JSON.parse(tr.attr('data-app-row'));
				rows.push (row);
				var pk = tr.attr('data-app-pk');
				var namekey = tr.attr('data-app-namepropertyid');
				// 选中的id转为数组，遍历其中是否包含主键值，如果包含，退出
				for (var i = 0; i < selectedValues.length; i ++) {
					if (selectedValues[i] == row[pk]) {
						return;
					}
				}
				if (singleSelect) {
					// 设置hidden值
					hidden.val(row[pk]);
					hidden.next().find('.form-control').empty();
				} else {
					// 添加当前选中行的主键值
					selectedValues.push(row[pk]);
					hidden.val(selectedValues.join(","));
				}
				// 添加按钮
				hidden.next().find('.form-control').append(MApp.createRelatedNameButtons(row[pk], row[namekey]));
			});
			if (appData.selectSuccessFn) {
				appData.selectSuccessFn(selectedValues, rows, appData);
			}
			if (appData.container == 'tab') {
				BigUtil.closeTab();
			} else {
				$(this).parents('.modal:first').modal('hide');
			}
		});
	},
	addRequestJson : function (appData, reqJson) {
		appData = BigUtil.clone({}, appData);
		var req = {};
		if (appData.requestjson) {
			req = JSON.parse(appData.requestjson);
		}
		if (reqJson) {
			if (typeof (reqJson) == 'string') {
				BigUtil.clone (req, JSON.parse(reqjson));
			} else if (reqJson.attr('data-app-requestjson')) {
				BigUtil.clone (req, JSON.parse(reqJson.attr('data-app-requestjson')));
			} else {
				BigUtil.clone (req, reqJson);
			}
		}
		appData.requestjson = JSON.stringify(req);
		return appData;
	},
	listBtnCreateInit : function (appData, listDiv) {
		// 列表外的创建按钮
		listDiv.prev().find('button[data-app-buttontype=create]').click (function () {
			BigUtil.openTab({
				title : '新建',
				url : '/meta/' + appData.type + '/loadCreateForm',
				params : MApp.addRequestJson(appData, $(this)),
				fn : function (tabContent) {
					var createForm = tabContent.find('[data-app-form=' + MApp.getDomId(appData) + '-form]');
					MApp.initForm (appData, createForm, true);
					createForm.find('button[data-app-buttontype=submitCreate]').click (function () {
						BigUtil.ajaxForm({
							form : createForm.find('form:first'),
							url : '/meta/' + appData.type + '/create',
							params : MApp.addRequestJson(appData, $(this)),
							success : function (json) {
								if (json.success) {
									BigUtil.closeTab();
									MApp.loadList(appData);
								} else {
									alert (json.msg);
								}
							}
						});
					});
				}
			});
		});
		// 列表行上的按钮
		listDiv.on('click', 'button[data-app-buttontype=create]', function (e) {
			var params = {selectedIds : MApp.getListRowPkValue($(this).parents('tr:first'))};
			BigUtil.clone(params, appData);
			BigUtil.openTab({
				title : '新建',
				url : '/meta/' + appData.type + '/loadCreateForm',
				params : MApp.addRequestJson(params, $(this)),
				fn : function (tabContent) {
					var createForm = tabContent.find('[data-app-form=' + MApp.getDomId(appData) + '-form]');
					MApp.initForm (appData, createForm, true);
					createForm.find('button[data-app-buttontype=submitCreate]').click (function () {
						BigUtil.ajaxForm({
							form : createForm.find('form:first'),
							url : '/meta/' + appData.type + '/create',
							params : MApp.addRequestJson(appData, $(this)),
							success : function (json) {
								if (json.success) {
									BigUtil.closeTab();
									MApp.loadList(appData);
								} else {
									alert (json.msg);
								}
							}
						});
					});
				}
			});
			e.stopPropagation();
		});
	},
	getListRowPkValue : function (tr) {
		var row = JSON.parse(tr.attr('data-app-row'));
		var pk = tr.attr('data-app-pk');
		return row[pk];
	},
	listBtnOpenTabInit : function (appData, listDiv) {
		// 列表行上的按钮
		listDiv.on('click', 'button[data-app-tabtype]', function (e) {
			MApp.clickBtnOpenTab($(this), MApp.getListRowPkValue($(this).parents('tr:first')), appData, true);
			e.stopPropagation();
		});
		// 列表上方的按钮
		listDiv.prev().find('button[data-app-tabtype]').click (function () {
			var selectType = $(this).attr('data-app-buttonselecttype');
			if (!MApp.validateListSelection(appData, listDiv, selectType)) {
				return;
			}
			MApp.clickBtnOpenTab($(this), MApp.getListPkValues(appData, listDiv).join(','), appData, true);
		});
	},
	listBtnRequestJsonInit : function (appData, listDiv) {
		listDiv.on('click', 'button[data-app-requesturl]', function (e) {
			if ($(this).hasClass('btn-danger') && !confirm ('该操作比较危险，确定要执行吗？')) {
				return;
			}
			var params = BigUtil.clone(MApp.parseData($(this)), MApp.addRequestJson(appData, $(this)));
			params['selectedIds'] = MApp.getListRowPkValue($(this).parents('tr:first'));
			var url = $(this).attr('data-app-requesturl');
			$.post(url, params, function (json) {
				if (json.success) {
					MApp.loadList(appData);
				} else {
					alert(json.msg);
				}
			});
			e.stopPropagation();
		});
		listDiv.prev().find('button[data-app-requesturl]').click (function () {
			var selectType = $(this).attr('data-app-buttonselecttype');
			if (!MApp.validateListSelection(appData, listDiv, selectType)) {
				return;
			}
			if ($(this).hasClass('btn-danger') && !confirm ('该操作比较危险，确定要执行吗？')) {
				return;
			}
			var params = BigUtil.clone(MApp.parseData($(this)), MApp.addRequestJson(appData, $(this)));
			params['selectedIds'] = MApp.getListPkValues(appData, listDiv).join(',');
			var url = $(this).attr('data-app-requesturl');
			$.post(url, params, function (json) {
				if (json.success) {
					MApp.loadList(appData);
				} else {
					alert(json.msg);
				}
			});
		});
	},
	listBtnOpenWindowInit : function (appData, listDiv) {
		listDiv.on('click', 'button[data-app-openurl]', function (e) {
			var url = BigUtil.appendQueryString ($(this).attr('data-app-openurl'), 'selectedIds=' + MApp.getListRowPkValue($(this).parents('tr:first')));
			window.open (url);
			e.stopPropagation();
		});
		listDiv.prev().find('button[data-app-openurl]').click (function () {
			var selectType = $(this).attr('data-app-buttonselecttype');
			if (!MApp.validateListSelection(appData, listDiv, selectType)) {
				return;
			}
			var url = BigUtil.appendQueryString ($(this).attr('data-app-openurl'), 'selectedIds=' + MApp.getListPkValues(appData, listDiv).join(','));
			window.open (url);
		});
	},
	listBtnDeleteInit : function (appData, listDiv) {
		listDiv.prev().find('button[data-app-buttontype=delete]').click(function () {
			var selectType = $(this).attr('data-app-buttonselecttype');
			if (!MApp.validateListSelection(appData, listDiv, selectType)) {
				return;
			}
			if (!confirm('该操作无法恢复，您确定吗？')) {
				return;
			}
			var data = MApp.addRequestJson(appData, $(this));
			data.selectedIds = MApp.getListPkValues(appData, listDiv).join(',');
			$.post('/meta/' + appData.type + '/delete', data, function (json) {
				if (json.success) {
					// BigUtil.closeTab();
					MApp.loadList(appData);
				} else {
					alert(json.msg);
				}
			});
		});
	},
	listBtnImportInit : function (appData, listDiv) {
		listDiv.prev().find('button[data-app-buttontype=import]').click(function () {
			var selectType = $(this).attr('data-app-buttonselecttype');
			if (!MApp.validateListSelection(appData, listDiv, selectType)) {
				return;
			}
			var data = MApp.addRequestJson(appData, $(this));
			data.selectedIds = MApp.getListPkValues(appData, listDiv).join(',');
			// 显示上传modal
			var modal = $('[data-bigupload]');
			modal.modal ('show');
			// 清空已经选择的文件
			modal.find('input[type=file]').val('');
			// 设置上传按钮点击事件
			modal.find('button:last').unbind();
			modal.find('button:last').click (function () {
				BigUtil.ajaxForm({
					url : '/meta/file',
					file : true,
					form : modal.find('form:first'),
					success : function (json) {
						if (json.success) {
							data.fileId = json.content.id;
							$.post('/meta/' + appData.type + '/import', data, function (json) {
								if (json.success) {
									modal.modal ('hide');
									MApp.loadList(appData);
								} else {
									alert(json.msg);
								}
							});
						}
					}
				});
			});
		});
	},
	listBtnUpdateInit : function (appData, listDiv) {
		listDiv.on('click', 'button[data-app-buttontype=update]', function (e) {
			var tr = $(this).parents('tr');
			var row = JSON.parse(tr.attr('data-app-row'));
			var pk = tr.attr('data-app-pk');
			var data = MApp.addRequestJson(appData, $(this));
			data.selectedIds = row[pk];
			BigUtil.openTab({
				title: $(this).text(),
				url: '/meta/' + appData.type + '/loadUpdateForm',
				params: data,
				fn: function (tabContent) {
					var updateForm = tabContent.find('[data-app-form=' + MApp.getDomId(appData) + '-form]');
					MApp.initForm(appData, updateForm, false);
					updateForm.find('button[data-app-buttontype=submitUpdate]').click(function () {
						// var data = BigUtil.mergeFormData(updateForm.find('form').serializeArray(), appData);
						BigUtil.ajaxForm({
							form : updateForm.find('form:first'),
							url : '/meta/' + appData.type + '/update',
							params : MApp.addRequestJson(appData, $(this)),
							success : function (json) {
								if (json.success) {
									BigUtil.closeTab();
									MApp.loadList(appData);
								} else {
									alert (json.msg);
								}
							}
						});
					});
				}
			});
			e.stopPropagation();
		});
	},
	/**
	 * 当crud.html加载完成后，初始化list视图的列表及其按钮
	 * @param appData
	 */
	listInit : function (appData) {
		var listDiv = MApp.listDiv(appData);
		var singleSelect = listDiv.attr('data-app-listsingleselect') == 'true';
		if (appData.selector == 'true') {
			singleSelect = (appData.selectorsingle == 'true');
		}

		// 设置列表行点击事件，设置选中样式，采用父元素代理
		listDiv.on ('click', 'tr', function () {
			// 表头则略过
			if ($(this).attr('data-app-row') == undefined) {
				return;
			}
			if (singleSelect) {
				if ($(this).hasClass(MApp.tableSelectedClass)) {
					$(this).removeClass(MApp.tableSelectedClass);
				} else {
					$(this).siblings().removeClass(MApp.tableSelectedClass);
					$(this).addClass(MApp.tableSelectedClass);
				}
			} else {
				$(this).toggleClass(MApp.tableSelectedClass);
			}
		});

		// 设置查询按钮点击事件
		listDiv.prev().find('button[data-app-buttontype=search]').click (function () {
			MApp.loadList(appData, 1);
		});

		// selector确定按钮点击事件
		MApp.listBtnSelectorInit(appData, listDiv, singleSelect);

		// 设置新建按钮点击事件
		MApp.listBtnCreateInit(appData, listDiv);

		// 设置删除按钮点击事件
		MApp.listBtnDeleteInit(appData, listDiv);

		// 设置导入按钮点击事件
		MApp.listBtnImportInit(appData, listDiv);

		// 设置修改按钮点击事件，采用父元素代理
		MApp.listBtnUpdateInit(appData, listDiv);

		// 设置requestJson按钮点击事件
		MApp.listBtnRequestJsonInit(appData, listDiv);
		
		// 设置openTab按钮点击事件
		MApp.listBtnOpenTabInit(appData, listDiv);
		
		// 设置openWindow按钮点击事件
		MApp.listBtnOpenWindowInit(appData, listDiv);
		
		// 设置分页按钮点击事件，采用父元素代理
		listDiv.on ('click', 'ul.pagination a', function () {
			MApp.loadList(appData, $(this).attr('data-app-page'));
		});
	},
	/**
	 * ${appData.type}.html加载后的回调，用于初始化应用
	 * @param appData
	 */
	crudInit : function (appData) {

		/**
		 *
		 */
		MApp.listInit(appData);

		// 加载列表数据
		MApp.loadList(appData);
	}
};

$(function () {
    MApp.load();
});